%_______________________________________________________________________________________%
%  Dwarf Mongoose Optimization Algorithm 
%_______________________________________________________________________________________%
function [BEF,BEP,BestCost]=DMOA(nPop,MaxIt,VarMin,VarMax,nVar,fobj)



%nVar=5;             % ���߱���������

VarSize=[1 nVar];   % ���߱��������С

%VarMin=-10;         % ���߱�������
%VarMax= 10;         % ���߱�������

%% ABC Settings

% MaxIt=1000;              % ����������

% nPop=100;               % �˿ڹ�ģ����ͥ��ģ��

nBabysitter= 3;         % ��ķ����

nAlphaGroup=nPop-nBabysitter;         % Alpha����

nScout=nAlphaGroup;         % ͯ�Ӿ�����

L=round(0.6*nVar*nBabysitter); % ��ķ��������

peep=2;             %������Ů��

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% ��è���ṹ
empty_mongoose.Position=[];
empty_mongoose.Cost=[];

% ��ʼ���˿�����
pop=repmat(empty_mongoose,nAlphaGroup,1);

%��ʼ����ʷ������õĽ������
BestSol.Cost=inf;
tau=inf;
Iter=1;
sm=inf(nAlphaGroup,1);

% ������ʼ��Ⱥ
for i=1:nAlphaGroup
    pop(i).Position=unifrnd(VarMin,VarMax,VarSize);
    pop(i).Cost=fobj(pop(i).Position);
    if pop(i).Cost<=BestSol.Cost
        BestSol=pop(i);
    end
end

% ������̨
C=zeros(nAlphaGroup,1);
CF=(1-Iter/MaxIt)^(2*Iter/MaxIt);

% ��������ֵ������
BestCost=zeros(MaxIt,1);

%% DMOA ��ѭ��

for it=1:MaxIt
    
    % ��������
     F=zeros(nAlphaGroup,1);
     MeanCost = mean([pop.Cost]);
    for i=1:nAlphaGroup
        
        % ������Ӧ��ֵ�� Alpha ��ѡ��
        F(i) = exp(-pop(i).Cost/MeanCost); %
    end
        P=F/sum(F);
      %�� Alpha Ů���쵼����ʳ
    for m=1:nAlphaGroup
        
        % 
        i=RouletteWheelSelection(P);
        
        % ���ѡ��k��������Alpha
        K=[1:i-1 i+1:nAlphaGroup];
        k=K(randi([1 numel(K)]));
        
        % ���巢��ϵ����
        phi=(peep/2)*unifrnd(-1,+1,VarSize);
        
        %��è��λ��
        newpop.Position=pop(i).Position+phi.*(pop(i).Position-pop(k).Position);
        
        %����
        newpop.Cost=fobj(newpop.Position);
        
        % �Ƚ�
        if newpop.Cost<=pop(i).Cost
            pop(i)=newpop;
        else
            C(i)=C(i)+1;
        end
        
    end   
    
    %�����
    for i=1:nScout
        
        % ���ѡ��k��������i
        K=[1:i-1 i+1:nAlphaGroup];
        k=K(randi([1 numel(K)]));
        
        % ���巢��ϵ����
        phi=(peep/2)*unifrnd(-1,+1,VarSize);
        
        % ��è��λ��
        newpop.Position=pop(i).Position+phi.*(pop(i).Position-pop(k).Position);
        
        %����
        newpop.Cost=fobj(newpop.Position);
        
        % ˯ģ
        sm(i)=(newpop.Cost-pop(i).Cost)/max(newpop.Cost,pop(i).Cost);
        
        %�Ƚ�
        if newpop.Cost<=pop(i).Cost
            pop(i)=newpop;
        else
            C(i)=C(i)+1;
        end
        
    end    
    % ��ķ
    for i=1:nBabysitter
        if C(i)>=L
            pop(i).Position=unifrnd(VarMin,VarMax,VarSize);
            pop(i).Cost=fobj(pop(i).Position);
            C(i)=0;
        end
    end    
     % �����ҵ�����ѽ������
    for i=1:nAlphaGroup
        if pop(i).Cost<=BestSol.Cost
            BestSol=pop(i);
        end
    end    
        
   % ��һ��è��λ��
   newtau=mean(sm);
   for i=1:nScout
        M=(pop(i).Position.*sm(i))/pop(i).Position;
        if newtau>tau
           newpop.Position=pop(i).Position-CF*phi*rand.*(pop(i).Position-M);
        else
           newpop.Position=pop(i).Position+CF*phi*rand.*(pop(i).Position-M);
        end
        tau=newtau;
   end
       
   % �����ҵ�����ѽ������
    for i=1:nAlphaGroup
        if pop(i).Cost<=BestSol.Cost
            BestSol=pop(i);
        end
    end
    
    %�洢��ʷ������õĳɱ�
    BestCost(it)=BestSol.Cost;
    BEF=BestSol.Cost;
    BEP=BestSol.Position;
    % ��ʾ������Ϣ
    disp(['Iteration ' num2str(it) ': Best Cost = ' num2str(BestCost(it))]);
    

end

